package com.aplink.generic.webservice;

import java.util.ArrayList;
import java.util.Iterator;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.text.TextUtils;

import com.aplink.generic.dictionary.GenericDictionary;
import com.aplink.generic.network.GenericFile;
import com.aplink.generic.pojo.ContentData;
import com.aplink.generic.pojo.GenericAttribute;
import com.aplink.generic.pojo.GenericObject;
import com.aplink.generic.pojo.ObjPropInfo;
import com.aplink.generic.util.BitmapUtis;

public class WebServiceParser {
    private volatile static WebServiceParser sInstance = null;

    public static WebServiceParser getInstance() {
        if (WebServiceParser.sInstance == null) {
            synchronized (WebServiceParser.class) {
                if (WebServiceParser.sInstance == null) {
                    WebServiceParser.sInstance = new WebServiceParser();
                }
            }
        }
        return WebServiceParser.sInstance;
    }

    public DataResult parse(String data, final ContentData objPropCol,
            final GenericObject passedValue) throws JSONException {
        if (data == null) {
            return null;
        }
        if (data.trim().startsWith("{")) {
            data = String.format("[%s]", data.trim());
        }
        final JSONArray jsonarray = new JSONArray(data);
        return this.parseJson(jsonarray, objPropCol, passedValue);
    }

    public DataResult parse(String data, final String tableName,
            final ContentData objPropCol) throws JSONException {
        if (data == null) {
            return null;
        }
        if (data.trim().startsWith("{")) {
            data = String.format("[%s]", data.trim());
        }
        final JSONArray jsonarray = new JSONArray(data);
        if (objPropCol == null) {
            return this.parseJson(jsonarray, tableName);
        }
        return this.parseJson(jsonarray, objPropCol, null);
    }

    private DataResult parseJson(final JSONArray jsonArray,
            final ContentData objPropCol,
            final GenericDictionary<String, GenericAttribute> listValue)
            throws JSONException {
        final DataResult dataResult = new DataResult();
        final ArrayList<GenericObject> genericObjects = new ArrayList<GenericObject>();
        for (int i = 0; i < jsonArray.length(); i++) {
            final JSONObject jsonResult = (JSONObject) jsonArray.get(i);
            if (jsonResult != null) {
                final ResponseStatus responseStatus = new ResponseStatus();
                if (jsonResult.has("Result")) {
                    final int result = jsonResult.getInt("Result");
                    responseStatus.setStatus(result);
                } else if (jsonResult.has("Description")) {
                    final String description = jsonResult
                            .getString("Description");
                    responseStatus.setDescription(description);
                } else {
                    responseStatus.setStatus(ResponseStatus.SUCCESS);
                }
                dataResult.setResponseStatus(responseStatus);
                if (responseStatus.getStatus() == ResponseStatus.SUCCESS) {
                    if (!objPropCol.isEmpty()) {
                        final GenericObject genericObject = new GenericObject();
                        genericObject.setTableName(objPropCol.getMainTable());
                        String imageLocalPath = null;
                        ObjPropInfo fileLocalPath = null;
                        for (int j = 0; j < objPropCol.size(); j++) {
                            final ObjPropInfo objPropInfo = objPropCol
                                    .valueAt(j);
                            final String name = objPropInfo.getFullColumnName();
                            final String webserviceVariable = objPropInfo
                                    .getWebserviceVariable();
                            GenericAttribute attribute = null;
                            if (!TextUtils.isEmpty(webserviceVariable)
                                    && jsonResult.has(webserviceVariable)) {
                                final String value = jsonResult.get(
                                        webserviceVariable).toString();
                                attribute = GenericAttribute.obtain(value,
                                        objPropInfo);
                                if (objPropInfo.isImageServerPath()) {
                                    if (!TextUtils.isEmpty(value)) {
                                        final GenericFile genericFile = BitmapUtis
                                                .getInstance().download(value);
                                        if (genericFile != null) {
                                            imageLocalPath = genericFile
                                                    .getLocalPath();
                                        }
                                    }
                                }
                            } else if ((listValue != null)
                                    && listValue.containsKey(name)) {
                                String value = null;
                                if ((listValue.get(name) != null)
                                        && (listValue.get(name).getValue() != null)) {
                                    value = listValue.get(name).getValue()
                                            .toString();
                                }
                                attribute = GenericAttribute.obtain(value,
                                        objPropInfo);
                            } else {
                                attribute = GenericAttribute.obtain(null,
                                        objPropInfo);
                            }
                            genericObject.put(name, attribute);
                            if (objPropInfo.isImageLocalPath()) {
                                fileLocalPath = objPropInfo;
                            }
                        }
                        if (fileLocalPath != null) {
                            genericObject.put(
                                    fileLocalPath.getFullColumnName(),
                                    imageLocalPath);
                        }
                        genericObjects.add(genericObject);
                    }
                }
            }
        }
        dataResult.setData(genericObjects);
        return dataResult;
    }

    private DataResult parseJson(final JSONArray jsonArray,
            final String tableName) throws JSONException {
        final ArrayList<GenericObject> genericObjects = new ArrayList<GenericObject>();
        final DataResult dataResult = new DataResult();
        for (int i = 0; i < jsonArray.length(); i++) {
            final JSONObject jsonObject = jsonArray.getJSONObject(i);
            final Iterator<?> keys = jsonObject.keys();
            if (jsonObject != null) {
                if (jsonObject.has("Result") && jsonObject.has("Description")) {
                    final int result = jsonObject.getInt("Result");
                    final String description = jsonObject
                            .getString("Description");
                    final ResponseStatus responseStatus = new ResponseStatus();
                    responseStatus.setDescription(description);
                    responseStatus.setStatus(result);
                    dataResult.setResponseStatus(responseStatus);
                }
                final GenericObject genericObject = new GenericObject();
                genericObject.setTableName(tableName);
                while (keys.hasNext()) {
                    final String key = (String) keys.next();
                    if (jsonObject.has(key)) {
                        final String value = jsonObject.getString(key);
                        final GenericAttribute attribute = new GenericAttribute(
                                key, value);
                        genericObject.put(tableName + "." + key, attribute);
                    }
                }
                genericObjects.add(genericObject);
            }
        }
        dataResult.setData(genericObjects);
        return dataResult;
    }
}
